/*
 * RCObject.cpp
 *
 *  Created on: Aug 22, 2014
 *      Author: Lucifer
 */

#include "RCObject.h"
#include "./Common.h"
#include <boost/thread.hpp>

#if PLATFORM == PLATFORM_WINDOWS
#include <Windows.h>
#else
#include <pthread.h>
#endif

namespace BFX {

static boost::thread_specific_ptr<RCObjectPool> __poolCur;

static RCObjectPool* RCObjectPool_tlsSet(RCObjectPool* pool) {
	// set new object and return current pool object.
	RCObjectPool* poolPrev = __poolCur.get();
	__poolCur.reset(pool);
	return poolPrev;
}
static RCObjectPool* RCObjectPool_tlsGet() {
	// get current pool object
	return __poolCur.get();
}

RCObject* RCObject::autoReleaseRef() {
	// Just put self into the current pool.
	RCObjectPool* curPool = RCObjectPool::currentPool();
	BFX_ASSERT(curPool);
	if (curPool) {
		curPool->addObject(this);
		return this;
	}
	return NULL;	// We need at least one object pool.
}

RCObjectPool::RCObjectPool() :
		_objects(32) {
	// push self into the pool stack.
	_poolPrev = RCObjectPool_tlsSet(this);
}

RCObjectPool::~RCObjectPool() {
	drain();
	// pop self from the pool stack.
	RCObjectPool_tlsSet(_poolPrev);
}

void RCObjectPool::addObject(RCObject* object) {
	if (object) {
		_objects.push_back(object);
	}
}

void RCObjectPool::drain() {
	_objects.clear();
}

RCObjectPool* RCObjectPool::currentPool() {
	// attempt to get current auto-release pool from TLS.
	RCObjectPool* curPool = RCObjectPool_tlsGet();
	BFX_ASSERT(curPool);
	return curPool;
}

} /* namespace BFX */
